/*
XPTracker - Alternative Agile Tracking Tool
Copyright (C) 2006-2009  Stephen Starkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package org.xptracker.services;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.apache.commons.logging.LogFactory;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.Scriptable;
import org.xptracker.domain.Domain;
import org.xptracker.persistence.PersistenceManager;
import org.xptracker.search.StoryIndexer;
import org.xptracker.services.reports.ReportFactory;

@Singleton
public class JsEngine {
  private Provider<PersistenceManager> mgr;
  private Provider<Domain> domain;
  private Provider<EmailService> emailService;
  private Provider<StoryIndexer> indexer;
  private Provider<ReportFactory> reporter;

  @Inject
  public JsEngine(Provider<PersistenceManager> mgr, Provider<Domain> domain, Provider<EmailService> emailService,
                  Provider<StoryIndexer> indexer, Provider<ReportFactory> reporter) {
    this.mgr = mgr;
    this.domain = domain;
    this.emailService = emailService;
    this.indexer = indexer;
    this.reporter = reporter;
  }

  public void withEngine(final EngineReceiver er) {
    withEngine(true, er);
  }

  public void withEngine(boolean includeServices, final EngineReceiver er) {
    final Context cx = Context.enter();
    final Scriptable scope = new ImporterTopLevel(cx, true);
    try {
      if (includeServices) {
        scope.put("mgr", scope, mgr.get());
        scope.put("domain", scope, domain.get());
        scope.put("emailer", scope, emailService.get());
        scope.put("searcher", scope, indexer.get());
        scope.put("reporter", scope, reporter.get());
        scope.put("log", scope, LogFactory.getLog(JsEngine.class.getName() + ".js"));
      }

      er.receive(cx, scope);
    } catch (Exception e) {
      LogFactory.getLog(JsEngine.class).error("Error during JavaScript Execution", e);
    } finally {
      Context.exit();
    }
  }
}
